﻿namespace RPCenter.WindowsAPI
{
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Text;

    public class NativeProcess
    {
        private const int CMDLINE_LENGTH_OFFSET = 0x40;
        private const int PROC_PARAMS_OFFSET = 0x10;

        public static string GetCommandLineX86(Process TargetProcess)
        {
            if (NativeOperatingSystem.Is64BitOperatingSystem && (!IsWow64Process(Process.GetCurrentProcess()) || !IsWow64Process(TargetProcess)))
            {
                throw new NotSupportedException("GetCommandLineX86 is not supported on a 64 bit operating system unless the calling process and target process are both 32 bit processes running in WOW64 mode (32 bit emulation)");
            }
            using (NativeMemoryReader reader = new NativeMemoryReader(TargetProcess))
            {
                ApiDefinitions.Process_Basic_Information processInformation = new ApiDefinitions.Process_Basic_Information();
                uint returnLength = 0;
                int error = ApiDefinitions.NtQueryInformationProcess(reader.TargetProcessHandle, 0, ref processInformation, Marshal.SizeOf(processInformation), ref returnLength);
                if (error != 0)
                {
                    throw new Win32Exception(error);
                }
                byte[] buffer3 = new byte[4];
                IntPtr memoryAddress = new IntPtr(processInformation.PebBaseAddress.ToInt32() + 0x10);
                buffer3 = reader.ReadMemory(memoryAddress, buffer3.Length - 1);
                if (buffer3 == null)
                {
                    throw new ApplicationException("Memory could not be read from PebBaseAddress + " + Conversions.ToString(0x10) + ". Ensure that you have access to the full range of memory specified");
                }
                IntPtr ptr2 = new IntPtr(BitConverter.ToInt32(buffer3, 0));
                byte[] buffer2 = new byte[8];
                memoryAddress = new IntPtr(ptr2.ToInt32() + 0x40);
                buffer2 = reader.ReadMemory(memoryAddress, buffer2.Length - 1);
                if (buffer2 == null)
                {
                    throw new ApplicationException("Memory could not be read from ProcessParameters + " + Conversions.ToString(0x40) + ". Ensure that you have access to the full range of memory specified");
                }
                int num = BitConverter.ToInt16(buffer2, 0);
                IntPtr ptr = new IntPtr(BitConverter.ToInt32(buffer2, 4));
                byte[] bytes = reader.ReadMemory(ptr, num - 1);
                reader.Close();
                return Encoding.Unicode.GetString(bytes).Trim();
            }
        }

        public static Process GetParentProcess(Process ChildProcess)
        {
            ApiDefinitions.Process_Basic_Information information=new ApiDefinitions.Process_Basic_Information { }; 
            
            uint returnLength = 0;
            int error = ApiDefinitions.NtQueryInformationProcess(ChildProcess.Handle, 0, ref information, Marshal.SizeOf(information), ref returnLength);
            if (error != 0L)
            {
                throw new Win32Exception(error);
            }
            foreach (Process process3 in Process.GetProcesses())
            {
                try
                {
                    if (process3.Id == ((int) information.InheritedFromUniqueProcessId))
                    {
                        return process3;
                    }
                }
                catch (Exception exception1)
                {
                    ProjectData.SetProjectError(exception1);
                    Exception exception = exception1;
                    ProjectData.ClearProjectError();
                }
            }
            return null;
        }

        public static bool IsWow64Process(Process TargetProcess)
        {
            bool flag = false;
            if (NativeDll.DoesMethodExistInDll("kernel32.dll", "IsWow64Process"))
            {
                ApiDefinitions.IsWow64Process(TargetProcess.Handle, out flag);
            }
            return flag;
        }
    }
}

